/*
 * Copyright 2006-2008 Michele Mostarda ( michele.mostarda@gmail.com ).
 * All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.graphnav.swing;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Defines a panel able to dock nodes.
 *
 * //TODO: replace the ClipboardPanel with a dock area.
 */
public class ClipboardPanel extends JPanel {

    /**
     * An implementation of TransferHandler that adds support for dropping
     * nodes. Dropping a node on a this component adds a new node.
     */
    class NodeTransferHandler extends TransferHandler {
        //The data type exported from JColorChooser.
        String mimeType = DataFlavor.javaJVMLocalObjectMimeType + ";class=org.graphnav.swing.Node";
        DataFlavor nodeFlavor;
        private boolean changesNode = true;

        NodeTransferHandler() {
            //Try to create a DataFlavor for node.
            try {
                nodeFlavor = new DataFlavor(mimeType);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

        /**
         * Overridden to import a node if it is available.
         * getChangesForegroundColor is used to determine whether
         * the foreground or the background color is changed.
         */
        public boolean importData(JComponent c, Transferable t) {
            //if(true) return true;
            if (hasNodeFlavor(t.getTransferDataFlavors())) {
                System.out.println("sssss");
                try {
                    Node n = (Node) t.getTransferData(nodeFlavor);
                    GraphPanel gp = (GraphPanel) c;
                    if (getChangesNode()) {
                        gp.setSelectedNode(n);
                    } else {
                        gp.setSelectedNode(n);
                    }
                    return true;
                } catch (UnsupportedFlavorException ufe) {
                    System.out.println("importData: unsupported data flavor");
                } catch (IOException ioe) {
                    System.out.println("importData: I/O exception");
                }
            }
            return false;
        }

        /**
         * Does the flavor list have a Color flavor?
         */
        protected boolean hasNodeFlavor(DataFlavor[] flavors) {
            if (nodeFlavor == null) {
                 return false;
            }

            for (int i = 0; i < flavors.length; i++) {
                if (nodeFlavor.equals(flavors[i])) {
                    return true;
                }
            }
            return false;
        }

        /**
         * Overridden to include a check for a color flavor.
         */
        public boolean canImport(JComponent c, DataFlavor[] flavors) {
            return hasNodeFlavor(flavors);
        }

        protected void setChangesNode(boolean flag) {
            changesNode = flag;
        }

        protected boolean getChangesNode() {
            return changesNode;
        }
    }


    private static final int MARGIN = 10;

    private static final Dimension SIZE = new Dimension(40, 0);

    private List<MovableShape> shapes;

    public ClipboardPanel() {
        shapes = new ArrayList<MovableShape>();
        setTransferHandler(new NodeTransferHandler() );
    }

    public void addShape(MovableShape s) {
        shapes.add(s);
        repaint();
    }

    public void removeShape(MovableShape s) {
        shapes.remove(s);
        repaint();
    }

    public Dimension getPreferredSize() {
         return SIZE;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        Graphics2D g2d = (Graphics2D) g;
        Iterator<MovableShape> shIter = shapes.iterator();
        MovableShape current = null;
        double currX = MARGIN;
        double currY = MARGIN;
        Graphics2D created = null;
        while( shIter.hasNext() ) {
            current = shIter.next();
            Rectangle2D bounds = current.getBounds2D(MovableShape.DETAIL_LEVEL_MEDIUM);
            created = (Graphics2D) g2d.create( (int) ( currX - bounds.getX() ), (int) ( currY - bounds.getY() ), getWidth(), getHeight() );
            current.paintShape(created, false, false, MovableShape.DETAIL_LEVEL_MEDIUM);
            currY += bounds.getHeight() + MARGIN;
            created.dispose();
        }
    }

}
